/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package cz.muni.fi.pb138.videolibrary.database;

import cz.muni.fi.pb138.videolibrary.exception.ElementAlreadyExistsException;
import cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;

/**
 * Rozhranie pre prácu s databázou.
 * @author Martin Hatina, Dominika Hoďovská
 */
public interface IDatabaseManager {    
    
    /**
     * @brief serializetoXML Transformuje modifikovanú databázu do XML súboru s danou URI
     * @param output URI súboru, do ktorého má byť transformovaná databáza
     * @throws IOException
     * @throws TransformerConfigurationException
     * @throws TransformerException 
     */
    public void serializetoXML(URI output) throws IOException, TransformerConfigurationException, TransformerException ;
    
    /**
     * @brief serializetoXML Transformuje modifikovanú databázu do daného XML súboru
     * @param output Súbor, do ktorého má byť transformovaná databáza
     * @throws IOException
     * @throws TransformerConfigurationException
     * @throws TransformerException 
     */
    public void serializetoXML(File output) throws IOException, TransformerConfigurationException, TransformerException ;
    
    /**
     * @return defaultný jazyk
     * @brief getter parametru defaultLanguage
     */
    public String getDefaultLanguage();
    
    /**
     * @param defaultLanguage defaultný jazyk
     * @brief setter parametru defaultLanguage
     */
    public void setDefaultLanguage(String defaultLanguage);
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.ElementAlreadyExistsException
     * @brief addMedium Pridanie média
     * @param medium Nové médium, ktorému bude pridelené ID.
     * @exception WrongNumberOfElementsException
     */
    public void addMedium(Medium medium) throws XPathExpressionException, WrongNumberOfElementsException, ElementAlreadyExistsException;
    
    /**
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @throws javax.xml.xpath.XPathExpressionException
     * @brief deleteMedium Odstránenie média
     * @param medium Médium, ktoré má byť odstránené.
     */
    public void deleteMedium(Medium medium) throws NoSuchElementException, WrongNumberOfElementsException, XPathExpressionException ;
    
    /**
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief updateMedium Zmena parametrov média. 
     * @param medium Modifikovaná inštancia média.
     */
    public void updateMedium(Medium medium) throws NoSuchElementException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief findMedium Vyhľadanie všetkých médií s názvom title.
     * Vyhľadanie je case-insensitive a title môže byť aj podslovo
     * @param title Reťazec, podľa ktorého hľadáme. 
     * @return Zoznam médií ktoré obsahujú hodnotu v parametri title
     */
    public ArrayList<Medium> findMedium(String title) throws XPathExpressionException, NoSuchElementException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief getAllMedia Vráti zoznam všetkých médií v databáze
     * @return Zoznam všetkých médií v databáze
     */
    public ArrayList<Medium> getAllMedia() throws XPathExpressionException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws WrongNumberOfElementsException
     * @brief getMedium Vyhľadá médium podľa ID
     * @param id ID média
     * @return nájdené médium alebo null
     */
    public Medium getMedium(long id) throws XPathExpressionException, NoSuchElementException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @throws cz.muni.fi.pb138.videolibrary.exception.ElementAlreadyExistsException
     * @brief addCategory Pridanie kategórie s novým ID
     * @param category Kategória, ktorá má byť pridaná
     */
    public void addCategory(Category category) throws XPathExpressionException, WrongNumberOfElementsException, ElementAlreadyExistsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @brief deleteCategory Odobranie kategórie
     * @param category Kategória na odobranie
     */
    public void deleteCategory(Category category) throws XPathExpressionException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @brief updateCategory Zmena kategórie
     * @param category Modifikovaná kategória
     */
    public void updateCategory(Category category) throws XPathExpressionException, NoSuchElementException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief Získanie kategórie z databázy
     * @param id ID kategórie, ktorá má byť nájdená
     * @return 
     */
    public Category getCategory(long id) throws NoSuchElementException, XPathExpressionException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief vyhladanie kategórie
     * @param title názov kategórie, ktorá má byť nájdená
     * @return vyhľadaná kategória
     */
    
    public ArrayList<Category> findCategory(String title) throws XPathExpressionException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief addToCategory Pridá kategóriu k danému médiu.
     * @param medium Médium, ktoré bude pridané do kategórie
     * @param category Kategória, ktorej bude pridané médium
     */
    public void addToCategory(Medium medium, Category category) throws XPathExpressionException, WrongNumberOfElementsException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @brief removeFromCategory odoberie medium zo vsetkych kategorii
     * @param medium Médium, ktoré bude odobrané z kategórii
     */
    public void removeFromCategories(Medium medium) throws XPathExpressionException;
    
    /**
     * @throws javax.xml.xpath.XPathExpressionException
     * @throws cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException
     * @brief getAllCategories Vráti zoznam kategórií
     * @return Zoznam všetkých kategórií
     */
    public ArrayList<Category> getAllCategories() throws XPathExpressionException, WrongNumberOfElementsException;
    
    /**
     * @brief importFrom importuje media z odf suboru
     * @param odf subor v ktorom sa nachadzaju media
     */
    public void importFrom(File odf);
    
    /**
     * @brief removeMediumFromCategory odstrani medium z kategorie
     * @param medium
     * @param category
     * @throws XPathExpressionException 
     */
    public void removeMediumFromCategory(Medium medium, Category category) throws XPathExpressionException;
}
